#include "GameLayer.h"
#include "GameInf.h"
#include "GameSettings.h"
#include "GameEnemy.h"
#include "MainScene.h"

#include "SimpleAudioEngine.h"

#include <time.h>

using namespace std;
using namespace CocosDenshion;

void GameLayer::initTile() {
	int i, j;
	for (i=3; i<width/tileWidth; i+=2) {
		for (j=2; j<height/tileHeight; j+=2) {
			CCSprite *shitou = CCSprite::createWithSpriteFrameName("shitou.png");
			this->addChild(shitou);
			shitou->setTag(0);
			tileArray->addObject(shitou);
			shitou->setPosition(ccp((i-0.5)*tileWidth, (j-0.5)*tileHeight));
		}
	}
	
	
	srand(10001);
	for (i=2; i<width/tileWidth+1; i+=1) {
		for (j=1; j<height/tileHeight+1; j+=2) {
			if ((i==2 && j==1) || (i==2&&j==2) || (i==3&&j==1)) {
				continue;
			}
			if (rand()%10 < 1) {
				CCSprite *zhuankuai = CCSprite::createWithSpriteFrameName("zhuankuai.png");
				this->addChild(zhuankuai);
				zhuankuai->setTag(1);
				zhuankuai->setPosition(ccp((i-0.5)*tileWidth, (j-0.5)*tileHeight));
				tileArray->addObject(zhuankuai);
			} else {
				CCPoint point = ccp((i-0.5)*tileWidth, (j-0.5)*tileHeight);
				nullPoints->addObject(&point);
			}
		}
	}
}
void GameLayer::initHero() {
	hero = new GameHero;
	hero->initAtPoint(heroStartPos, this);
}


void GameLayer::initEnemy() {
	srand(100001);
	for (int i=0; i<EnemyNum; i++) {
		CCPoint *point = (CCPoint *)nullPoints->objectAtIndex(rand()%(nullPoints->count()));
		GameEnemy *enemy = new GameEnemy();
		enemy->initAtPositionInLayer(*point, this);
		enemyArray->addObject(enemy);
		nullPoints->removeObject(point);
		enemy->tileArray = this->tileArray;
	}
}
void GameLayer::initBomb() {
	bomb = CCSprite::spriteWithSpriteFrameName("bomb.png");
	CCScaleTo *scale1 = CCScaleTo::actionWithDuration(0.5, 1.2);
	CCScaleTo *scale2 = CCScaleTo::actionWithDuration(0.5, 0.8);
	CCFiniteTimeAction *seq = CCSequence::actions(scale1, scale2, NULL);
	CCRepeatForever *repeat = CCRepeatForever::actionWithAction((CCActionInterval *)seq);
	bomb->runAction(repeat);
	this->addChild(bomb, -1);
	tileArray->addObject(bomb);
	bomb->setVisible(false);
	SimpleAudioEngine::sharedEngine()->preloadEffect("dingshi.mp3");
	SimpleAudioEngine::sharedEngine()->preloadEffect("baozha.mp3");
}


bool GameLayer::init() {
	bool bRet = false;

	do {
		CC_BREAK_IF( !CCLayer::init());

		width = 416;
		height = 288;
		tileWidth = tileHeight = TileWidth;
		GameInf *gameInf = GameInf::sharedGameInf();
		level = gameInf->level;
		score = gameInf->score;
		time = 120;

		reInit();

		bRet = true;
	} while (0);

	return bRet;

}


void GameLayer::reInit() {
	CCSprite *leftBoard = CCSprite::create("board.png");
	//CC_BREAK_IF( !leftBoard );
	leftBoard->setAnchorPoint(CCPointZero);
	leftBoard->setPosition(ccp(0, TileHeight));
	this->addChild(leftBoard);

	CCSprite *rightBoard = CCSprite::create("board.png");
	//CC_BREAK_IF( !rightBoard );
	rightBoard->setAnchorPoint(CCPointZero);
	rightBoard->setPosition(ccp(14*TileWidth, TileHeight));
	this->addChild(rightBoard);

	scoreLabel = CCLabelTTF::create("score: "+score, "Marker Felt", 32);
	//CC_BREAK_IF( !scoreLabel );
	scoreLabel->setPosition(ccp(11.5*TileWidth, winHeight-TileHeight/2));
	
	levelLabel = CCLabelTTF::create("level: "+level, "Marker Felt", 32);
	//CC_BREAK_IF( !levelLabel );
	levelLabel->setPosition(ccp(2.5*TileWidth, winHeight-TileHeight/2));

	timeLabel = CCLabelTTF::create("time: "+time, "Marker Felt", 32);
	//CC_BREAK_IF( !timeLabel );
	timeLabel->setPosition(ccp(7*TileWidth, winHeight-TileHeight/2));

	this->addChild(scoreLabel);
	this->addChild(levelLabel);
	this->addChild(timeLabel);

	time = 120;
	isBomb = false;
	isKey = false;
	nullPoints = CCArray::create();
	tileArray = CCArray::create();
	enemyArray = CCArray::create();

	SimpleAudioEngine::sharedEngine()->playBackgroundMusic("chaojimali.m4a", true);

	heroStartPos = ccp(48, 16);

	this->initTile();
	this->initHero();
	this->initEnemy();
	this->initBomb();
}

void GameLayer::pubBombEffect() {
	bombEffect = CCSprite::spriteWithSpriteFrameName("bombEffects.png");
	bombEffect->setScale(0.333);
	CCScaleTo *scale = CCScaleTo::actionWithDuration(0.3, 1);
	CCSequence *seq = CCSequence::actionOneTwo(scale, CCHide::action());
	bombEffect->runAction(seq);
	this->addChild(bombEffect, -1);
	bombEffect->setPosition(bomb->getPosition());
}

void GameLayer::putBomb() {
	if (isBomb) {
		return;
	}

	bomb->setVisible(true);
	this->schedule(schedule_selector(GameLayer::bombDown), 3);

	CCPoint pos = hero->heroSprite->getPosition();
	pos = this->convertToTilePos(pos);
	bomb->setPosition(pos);
	isBomb = true;
	SimpleAudioEngine::sharedEngine()->playEffect("dingshi.mp3");
}

void GameLayer::bombDown(float f) {
	CCSprite *tile;

	srand(232384);
	for (int i=0; i<tileArray->count(); i++) {
		tile = (CCSprite *)tileArray->objectAtIndex(i);
		if (ccpDistance(tile->getPosition(), bomb->getPosition()) <= TileHeight && tile->getTag()==1) {
			tileArray->removeObject(tile);
			tile->removeFromParentAndCleanup(false);
			score += 10;
			i--;
			scoreLabel->setString("score: "+score);
		}

		if (tileArray->count()==28 && !isKey) {
			key = CCSprite::spriteWithFile("yaoshi.png");
			this->addChild(key, -1);
			
			CCSprite *tile = (CCSprite *)tileArray->objectAtIndex(rand()%3+24);
			key->setPosition(tile->getPosition());
			isKey = true;
		}
	}

	for (int i=0; i<enemyArray->count(); i++) {
		GameEnemy *enemy = (GameEnemy *)enemyArray->objectAtIndex(i);
		if ((fabs(bomb->getPosition().x-enemy->getPosition().x)<TileWidth || fabs(bomb->getPosition().y-enemy->getPosition().y)<TileHeight) 
			&& ccpDistance(bomb->getPosition(), enemy->getPosition())<=TileWidth*2) {
				enemyArray->removeObject(enemy);
				enemy->unschedule(schedule_selector(GameEnemy::enemyMove));
				enemy->enemyKill();
				score += 100;
				i--;
				scoreLabel->setString("score: "+score);

		}
	}

	if ((fabs(bomb->getPosition().x-hero->heroSprite->getPosition().x)<TileWidth || fabs(bomb->getPosition().y-hero->heroSprite->getPosition().y)<TileHeight)) {
		this->gameOver();
	}

	bomb->setVisible(false);
	isBomb = false;
	this->pubBombEffect();
	bomb->setPosition(ccp(-16, -16));
	SimpleAudioEngine::sharedEngine()->playEffect("baozha.mp3");
	this->unschedule(schedule_selector(GameLayer::bombDown));
}


CCPoint GameLayer::convertToTilePos(cocos2d::CCPoint pos) {
	int x = pos.x/TileWidth;
	int y = pos.y/TileHeight;
	return ccp((x+0.5)*TileWidth, (y+0.5)*TileHeight);
}

void GameLayer::gameOver() {
	this->unschedule(schedule_selector(GameLayer::gameUpdate));
	GameInf *gameinf = GameInf::sharedGameInf();
	gameinf->score = 0;
	gameinf->level = 1;
	CCScene *scene = MainScene::scene();
	CCTransitionShrinkGrow *transitionScene = CCTransitionShrinkGrow::transitionWithDuration(3, scene);
	CCDirector::sharedDirector()->replaceScene(transitionScene);
		
}

void GameLayer::gameWin() {
	this->unschedule(schedule_selector(GameLayer::gameUpdate));
	GameInf *gameinf = GameInf::sharedGameInf();
	gameinf->score = score;
	gameinf->level = ++level;
	CCScene *scene = MainScene::scene();
	CCTransitionShrinkGrow *transitionScene = CCTransitionShrinkGrow::transitionWithDuration(3, scene);
	CCDirector::sharedDirector()->replaceScene(transitionScene);
}

void GameLayer::loadNextLevel(int level) {
	this->level = level;
	this->reInit();
}

void GameLayer::checkGameState() {
	if (enemyArray->count()==0 && hero->heroSprite->getPosition().x==key->getPosition().x && hero->heroSprite->getPosition().y==key->getPosition().y) {
		this->gameWin();
	}
	if (time<=0) {
		this->gameOver();
	}

}


void GameLayer::checkHeroState() {

	switch (hero->kact) {
		case 1:
			hero->moveUp();
			break;
		case 2:
			hero->moveLeft();
			break;
		case 3:
			hero->moveRight();
			break;
		case 4:
			hero->moveDown();
			break;
		case 5:
			this->putBomb();
			break;
		case 6:
			hero->onStay();
			break;
		default:
			break;
	}

	for (int i=0; i<enemyArray->count(); i++) {
		GameEnemy *enemy = (GameEnemy *)enemyArray->objectAtIndex(i);
		if (ccpDistance(enemy->getPosition(), hero->heroSprite->getPosition())<tileWidth-abs(enemy->speed)) {
			this->gameOver();
		}
	}
}

void GameLayer::updateTime() {

	static int i = 0;
	if (i==10) {
		time--;
		timeLabel->setString("time: "+time);
		i=0;
	}
	i++;
}

void GameLayer::gameUpdate(float f) {
	this->updateTime();
	this->checkHeroState();
	this->checkGameState();
}

/*
GameLayer* GameLayer::create() {
	GameLayer *gl = new GameLayer();
	if (gl && gl->init()) {
		gl->autorelease();
		return gl;
	} else {
		delete gl;
		gl = NULL;
		return gl;
	}
}
*/